package com.boyi.shared.util;

import org.apache.commons.lang3.StringUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 获取mac地址
 *
 * @author 颜培轩
 * @date 2018年01月18日  上午 09:30
 */
public class MacAddressUtil {
	private MacAddressUtil() {
	}

	public static String callCmd(String[] cmd) {
		String result = "";
		String line = "";
		try {
			Process proc = Runtime.getRuntime().exec(cmd);
			InputStreamReader is = new InputStreamReader(proc.getInputStream());
			BufferedReader br = new BufferedReader(is);
			while ((line = br.readLine()) != null) {
				result += line;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * @param cmd     第一个命令
	 * @param another 第二个命令
	 * @return 第二个命令的执行结果
	 */
	public static String callCmd(String[] cmd, String[] another) {
		String result = "";
		String line = "";
		try {
			Runtime rt = Runtime.getRuntime();
			Process proc = rt.exec(cmd);
			proc.waitFor(); //已经执行完第一个命令，准备执行第二个命令
			proc = rt.exec(another);
			InputStreamReader is = new InputStreamReader(proc.getInputStream());
			BufferedReader br = new BufferedReader(is);
			while ((line = br.readLine()) != null) {
				result += line;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}


	/**
	 * @param ip           目标ip,一般在局域网内
	 * @param sourceString 命令处理的结果字符串
	 * @param macSeparator mac分隔符号
	 * @return mac地址，用上面的分隔符号表示
	 */
	public static String filterMacAddress(final String ip, final String sourceString, final String macSeparator) {
		String result = "";
		String regExp = "((([0-9,A-F,a-f]{1,2}" + macSeparator + "){1,5})[0-9,A-F,a-f]{1,2})";
		Pattern pattern = Pattern.compile(regExp);
		Matcher matcher = pattern.matcher(sourceString);
		while (matcher.find()) {
			result = matcher.group(1);
			if (sourceString.indexOf(ip) <= sourceString.lastIndexOf(matcher.group(1))) {
				break; //如果有多个IP,只匹配本IP对应的Mac.
			}
		}

		return result;
	}


	/**
	 * @param ip 目标ip
	 * @return Mac Address
	 */
	public static String getMacInWindows(final String ip) {
		String result = "";
		String[] cmd = {
				"cmd",
				"/c",
				"ping " + ip
		};
		String[] another = {
				"cmd",
				"/c",
				"arp -a"
		};

		String cmdResult = callCmd(cmd, another);
		result = filterMacAddress(ip, cmdResult, "-");

		return result;
	}

	/**
	 * @param ip 目标ip
	 * @return Mac Address
	 */
	public static String getMacInLinux(final String ip) {
		String result = "";
		String[] cmd = {
				"/bin/sh",
				"-c",
				"ping " + ip + " -c 2 && arp -a"
		};
		String cmdResult = callCmd(cmd);
		result = filterMacAddress(ip, cmdResult, ":");

		return result;
	}

	/**
	 * 获取MAC地址
	 *
	 * @return 返回MAC地址
	 */
	public static String getMacAddress(String ip) {
		String macAddress = "";
		String systemName = System.getProperty("os.name");
		//判断当前环境，如果是Windows 要截取路径的第一个 '/'
		if (!StringUtils.isBlank(systemName) && systemName.toLowerCase().indexOf("windows") != -1) {
			macAddress = getMacInWindows(ip).trim();
		} else if (!StringUtils.isBlank(systemName) && systemName.toLowerCase().indexOf("linux") != -1) {
			macAddress = getMacInLinux(ip).trim();
		}
		return macAddress;
	}

	//获取服务器MAC
	public static String getLocalMac() throws SocketException, UnknownHostException {
		// TODO Auto-generated method stub
		//获取网卡，获取地址
		InetAddress ia = InetAddress.getLocalHost();
		byte[] mac = NetworkInterface.getByInetAddress(ia).getHardwareAddress();
		StringBuffer sb = new StringBuffer("");
		for (int i = 0; i < mac.length; i++) {
			if (i != 0) {
				sb.append("-");
			}
			//字节转换为整数
			int temp = mac[i] & 0xff;
			String str = Integer.toHexString(temp);
			if (str.length() == 1) {
				sb.append("0" + str);
			} else {
				sb.append(str);
			}
		}
		return sb.toString().toUpperCase();
	}

	//获取客户端ip
	public static String getMacAddrByIp(String ip) {
		String macAddr = null;
		try {
			Process process = Runtime.getRuntime().exec("nbtstat -a " + ip);
			BufferedReader br = new BufferedReader(
					new InputStreamReader(process.getInputStream()));
			Pattern pattern = Pattern.compile("([A-F0-9]{2}-){5}[A-F0-9]{2}");
			Matcher matcher;
			for (String strLine = br.readLine(); strLine != null;
				 strLine = br.readLine()) {
				matcher = pattern.matcher(strLine);
				if (matcher.find()) {
					macAddr = matcher.group();
					break;
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return macAddr;
	}


	public static void main(String[] args) throws SocketException, UnknownHostException {

		System.out.println("localMac = " + MacAddressUtil.getLocalMac());
		System.out.println("localMac = " + MacAddressUtil.getMacAddrByIp("192.168.1.135"));

	}
}